package pl.edu.uj.tcs.blef.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;


public final class Table extends Thread {
	
	private ServerSocket socket;
	private TableListener tableListener;
	private TableRequestHeadquarters headquarters;
	private String identifier;
	private String operator;
	private boolean running;
	private volatile Vector<Client> players;
	private volatile LinkedList<Client> awaitingPlayers;
	private volatile LinkedList<Client> incomingPlayers;
	private volatile LinkedList<Client> lostPlayers;
	private volatile Client operatorClient;
	private volatile Client lastTurnClient;
	private volatile Game game;
	
	public Table(String identifier, String operator) throws IOException{
		this.socket = new ServerSocket(0);
		this.tableListener = new TableListener(this, socket);
		this.headquarters = new TableRequestHeadquarters(this);
		this.players = new Vector<Client>();
		this.identifier = identifier;
		this.operator = operator;
		this.running = true;
		
		this.awaitingPlayers = new LinkedList<Client>();
		this.incomingPlayers = new LinkedList<Client>();
		this.lostPlayers = new LinkedList<Client>();
		
		start();
	}
	
	@Override
	public void run(){
		while(running){}
	}
	
	void removeConnection(Socket socket){
		if(operatorClient.getSocket().equals(socket)){
			this.operatorClient = null;
		}
		
		Iterator<Client> it = players.iterator();
		while(it.hasNext()){
			Client c = it.next();
			if(c.getSocket().equals(socket)) it.remove();
		}
		
		it = awaitingPlayers.iterator();
		while(it.hasNext()){
			Client c = it.next();
			if(c.getSocket().equals(socket)) it.remove();
		}
		
		it = incomingPlayers.iterator();
		while(it.hasNext()){
			Client c = it.next();
			if(c.getSocket().equals(socket)) it.remove();
		}
		
		it = lostPlayers.iterator();
		while(it.hasNext()){
			Client c = it.next();
			if(c.getSocket().equals(socket)) it.remove();
		}
	}
	
	public void checkTerminate(){
		if(this.players.size() == 0 || operatorClient == null){
			try {
				for(Client c: players) c.getSocket().close();
				for(Client c: awaitingPlayers) c.getSocket().close();
				for(Client c: incomingPlayers) c.getSocket().close();
				for(Client c: lostPlayers) c.getSocket().close();
				
				GlobalSettings._MAIN_SERVER_.removeTable(this);
				this.tableListener.terminate();
				this.running = false;
				this.socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public Vector<Client> getPlayers(){
		return this.players;
	}
	
	public LinkedList<Client> getAwaitingPlayers(){
		return this.awaitingPlayers;
	}
	
	public LinkedList<Client> getIncomingPlayers(){
		return this.incomingPlayers;
	}
	
	public LinkedList<Client> getLostPlayers(){
		return this.lostPlayers;
	}
	
	TableRequestHeadquarters getHeadquarters(){
		return this.headquarters;
	}
	
	String getIdentifier(){
		return this.identifier;
	}
	
	String getOperatorName(){
		return this.operator;
	}
	
	TableListener getListener(){
		return this.tableListener;
	}
	
	public void newGane(){
		this.game = new Game(this);
	}
	
	public boolean isOperator(Socket socket){
		return this.operatorClient.getSocket().equals(socket);
	}
	
	public int getPort(){
		return socket.getLocalPort();
	}
	
	void setOperator(Client c){
		this.operatorClient = c;
		this.lastTurnClient = c;
	}
	
	public Client getOperator(){
		return this.operatorClient;
	}
	
	public Client getLastTurnPlayer(){
		return this.lastTurnClient;
	}
	
	void setLastTurnPlayer(Client c){
		this.lastTurnClient = c;
	}
	
	public Game getGame(){
		return this.game;
	}
	
	public void setNewGame(){
		this.game = new Game(this);
	}
	
	public void setNewDeal(){
		this.game.setNewDeal();
	}
}
